package com.atguigu.day5;

import java.util.concurrent.TimeUnit;

public class VolatileSeeDemo {
    /*
     * 当把变量声明为volatile类型后，
     *
     * 编译器与运行时都会注意到这个变量是共享的！
     * 因此不会将该变量上的操作与其他内存操作一起重排序，用来确保将变量的更新操作通知到其他线程。
     *
     *工作内存与主内存同步延迟想象导致的可见性问题
     * 可以使用synchronized或volatile关键字解决，它们都可以使一个线程修改后的变量立即对其他线程可见！
     * */

    static /*volatile*/ Integer flag = 1;

    public static void main(String[] args) {
        new Thread(() -> {
            System.out.println("子线程工作内存读取到的flag的值" + flag);
            while (flag == 1) {
                System.out.println("test");
                /*
                *  System.out.println涉及到 I/O 操作，这些操作可能会触发 JVM 的内存屏障（memory barrier），
                * 从而强制刷新工作内存中的缓存数据到主内存中，并从主内存中重新加载最新的数据到工作内存。
                * 这是因为 I/O 操作可能会涉及同步机制，从而使得内存中的数据同步到磁盘或其他持久存储中。
                * */
            }
            System.out.println("子线程工作内存读取到的flag的最新值" + flag);

        }, "t1").start();

        //暂停几秒钟线程
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //主线程修改flag的值
        flag = 2;
        System.out.println("我是主线程工作内存flag的值：" + flag);
    }
}
